#ifndef __WIZ_UTILS_TOKENIZER_HPP__SHANHAOBO_19800429__
#define __WIZ_UTILS_TOKENIZER_HPP__SHANHAOBO_19800429__

/// LEXICAL
#include "../../Base/WizBase.hpp"
#include "../../Core/Container/WizDataTypeStack.hpp"

#include "./WizUtilsTokenizerResult.hpp"

namespace Wiz
{
    namespace Tokenizer
    {
        enum eFlags
        {
            eDefaultSeparators  = WIZ_BITS_DEF(0),
            eSeparators         = WIZ_BITS_DEF(1),
            eQuote              = WIZ_BITS_DEF(2),      /// 
            eBrackets           = WIZ_BITS_DEF(3),      ///
        };
        enum eRecordState
        {
            eRecordBegin,
            eRecording,
            eRecordEnd,
        };
        struct ParseState
        {
            ::Wiz::Char::ConstPtr           EndPtr;
            ::Wiz::Bool::Type               IsInQuote;
            ::Wiz::Stack::Type<::Wiz::Char::Type> BracketStack;
            eRecordState                    RecordState;
        };

        class WIZ_EXPORT Type
        {
        public:
            Type();
            Type(::Wiz::UInt32::In F) : m_Flags(F)
            {}
            ~Type();
        public:
            ::Wiz::Bool::Type Parse(::Wiz::Tokenizer::Result::Out Result, ::Wiz::String::In IStr)
            {
                ::Wiz::Size::Type ISize = IStr.Size();
                ::Wiz::Char::Ptr TempStr = new ::Wiz::Char::Type[ISize + 1];
                memcpy(TempStr, IStr.GetCStr(), ISize);
                TempStr[ISize] = '\0';
                if (DoParse(Result, TempStr, ISize))
                {
                    Result.SetOriginStr(TempStr, ISize);
                    return ::Wiz::Bool::True;
                }
                delete[] TempStr;
                return ::Wiz::Bool::False;
            }
        protected:
            virtual ::Wiz::Bool::Type DoParse(::Wiz::Tokenizer::Result::Out Result, ::Wiz::Char::ConstPtr Str, ::Wiz::Size::In Size);
        public:
            ::Wiz::Void::Type SetSeparators(::Wiz::String::In Seps)
            {
                m_Separators = Seps;
            }
            ::Wiz::Void::Type SetSeparators(::Wiz::Char::ConstPtr Seps)
            {
                SetSeparators(::Wiz::String::Type(Seps));
            }
            ::Wiz::Bool::Type IsSeparator(::Wiz::Char::In C)
            {
                return m_Separators.HasChar(C);
            }
            ::Wiz::Bool::Type ProcessQuote(::Wiz::Char::In C, ParseState& PS, ::Wiz::Size::InOut CurrPos);
            ::Wiz::Bool::Type ProcessDefaultSeparator(::Wiz::Char::In CurrChar, ParseState& PS, ::Wiz::Size::InOut CurrPos);
            ::Wiz::Bool::Type ProcessSeparator(::Wiz::Char::In C, ParseState& PS, ::Wiz::Size::InOut CurrPos);
            ::Wiz::Bool::Type ProcessBracket(::Wiz::Char::In C, ParseState& PS, ::Wiz::Size::InOut CurrPos);
        protected:
            ::Wiz::String::Type     m_Separators;
            ::Wiz::UInt32::Type     m_Flags;
        }; /// end of class Type
    } /// end of namespace Tokenizer
} /// end of namespace Wiz

#endif /*__WIZ_UTILS_TOKENIZER_HPP__SHANHAOBO_19800429__*/
